<?php

namespace App\Console\Commands;

use App\Constants\RedisKey;
use App\Models\AdminBankIcon;
use App\Models\UserFollowCacheDay;
use App\Models\UserFollowCacheHour;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class UserFollowCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'user-follow:data {action : insert|test|cacheHour|cacheDay} {--date=} {--type=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'user-follow datas';

    /**
     * The console command action. month|common|money|help
     *
     * @var string
     */
    protected $action;


    /**
     * Description: 把redis中的埋点记录存入数据库
     * Author: cg
     * Date: 2019-3-19 12:30
     */
    public function insert()
    {
        $arr = [];
        $cur_len = 0;
        while ($list = Redis::rPop(RedisKey::USER_FOLLOW)) {
            $cur_len++;
            $data = json_decode($list, true);
            array_push($arr, $data);
            if ($cur_len >= 25000) {
                break;
            }
        }
        $chunkArr = array_chunk($arr, 2500);
        foreach ($chunkArr as $insertArr) {
            try {
                DB::beginTransaction();
                DB::table('user_follows')->insert($insertArr);
                DB::commit();
                $this->info('埋点消费成功数据-' . count($insertArr));
            } catch (\Exception $e) {
                $this->info('埋点消费失败-' . $e->getMessage());
                DB::rollBack();
                foreach ($insertArr as $value) {
                    $json = json_encode($value, JSON_UNESCAPED_UNICODE);
                    Redis::lPush(RedisKey::USER_FOLLOW, $json);
                }
            }
        }
    }


    /**
     * 按小时缓存数据到user_follow_cache_hour 表
     */
    public function cacheHour()
    {
        /**
         * 执行命令:
         * php artisan user-follow:data cacheHour --date=20190408-12  {--type=}
         * 说明: type 可选参数: 默认为空   按指定日期查询 前一个小时的统计数据入库
         *                      不为空   按指定日期查询 前一个小时到当前时间的统计数据入库
         */

        $date = $this->option('date');
        $type = $this->option('type');
        $this->info("缓存落库 执行: 时间 : " . date('Y-m-d H:i:s', time()) . PHP_EOL);

        if (!$date) {
            $day = date('Y-m-d', time());
            $hour = date('H', time());
        } else {
            $dateArr = explode('-', $date);
            $day = substr($dateArr[0], 0, 4) . '-' . substr($dateArr[0], 4, 2) . '-' . substr($dateArr[0], -2);
            $hour = $dateArr[1];
        }

        $userFollowCache = new UserFollowCacheHour();

        if ($date && $type) {
            $now = date('Y-m-d H:i:s', time());
            $next = $day . ' ' . $hour . ':00:00';
            while ($next < $now) {
                $nextOneTime = strtotime('+1 hour', strtotime($next));
                $next = date('Y-m-d H:i:s', $nextOneTime);
                $day = date('Y-m-d', $nextOneTime);
                $hour = date('H', $nextOneTime);
                $res = $userFollowCache->cacheHourData($day, $hour);
                if ($res) {
                    $this->info("Insert database successful for CacheHour time : {$day} {$hour}:00:00 \n");
                }
            }
        } else {
            $res = $userFollowCache->cacheHourData($day, $hour);
            if ($res) {
                $this->info("Insert database successful for CacheHour time : {$day} {$hour}:00:00 \n");
            }
        }
    }

    /**
     * 按天缓存数据到 user_follow_cache_day 表
     */
    public function cacheDay()
    {
        /**
         * 执行命令:
         * php artisan user-follow:data cacheDay --date=20190401  {--type=}
         * 说明: type 可选参数: 默认为空  查询指定天 的 前一天统计数据入库
         *                      不为空  查询指定天 的 前一天 到  当前 时间的 统计数据入库
         */
        $date = $this->option('date');
        $type = $this->option('type');
        $this->info("缓存落库 执行: 时间 : " . date('Y-m-d H:i:s', time()) . PHP_EOL);

        if (!$date) {
            $day = date('Y-m-d', time());
        } else {
            $day = substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, -2);
        }

        $userFollowCache = new UserFollowCacheDay();

        if ($date && $type) {
            $now = date('Y-m-d', time());
            while ($day < $now) {
                $tomorrow = strtotime('+1 day', strtotime($day));
                $day = date('Y-m-d', $tomorrow);
                $res = $userFollowCache->cacheDayData($day);
                if ($res) {
                    $this->info("Insert database successful for cacheDay time : {$day}  \n  SQL : \n  {$res}");
                }
            }
        } else {
            $res = $userFollowCache->cacheDayData($day);
            if ($res) {
                $this->info("Insert database successful for cacheDay time : {$day}  \n  SQL : \n  {$res}");
            }
        }
    }


    /**
     * 同步 线上只读数据库数据到本地环境  user_follow 表  默认同步 5万条数据
     * 用于 cacheHour cacheDay 的本地数据缓存 线上数据库太大,迁移数据比较麻烦
     */
    public function testSyncDataByBackend()
    {
        /**
         *  执行命令:
         *  php artisan user-follow:data testSyncDataByBackend
         */
        $allPage = 50;
        $page = 1;
        $pageSize = 1000;
        $start = ($page - 1) * $pageSize;
        $count = 0;
        $db_keys_obj = DB::connection('backend')->select("desc user_follows");
        $db_keys_arr = array_reduce($db_keys_obj, function ($carry, $item) {
            $carry[] = $item->Field;
            return $carry;
        });

        while ($page < $allPage) {
            $sql = "select `" . implode('`,`', $db_keys_arr) . "` from user_follows order by id asc limit {$start} , {$pageSize}";
            $backendObjDatas = DB::connection('backend')->select($sql);
            $count += count($backendObjDatas);
            if ($count > 0) {
                foreach ($backendObjDatas as $backendObjData) {
                    $tmpArr = get_object_vars($backendObjData);
                    unset($tmpArr['id']);
                    DB::connection()->table('user_follows')->insert($tmpArr);
                }
                $page++;
                $this->info("Insert database successful for UserFollows , page : {$page} count : {$count}  \n");
            } else {
                $allPage = 0;
            }
        }

        $this->info("SyncData : " . $count . " \n ");
    }

    public function test()
    {

    }


    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->initAction();
        $this->runAction();
    }


    /**
     * Description: Initialize command action.
     * Author: Gxs
     */
    protected function initAction()
    {
        $this->action = $this->argument('action');

        if (!in_array($this->action, ['insert', 'test', 'cacheHour', 'cacheDay', 'testSyncDataByBackend'])) {
            $this->error("Invalid argument '{$this->action}'. Expected .");
            exit(1);
        }
    }

    /**
     * Description: Run action.
     * Author: Gxs
     */
    protected function runAction()
    {
        $this->{$this->action}();
    }


}
